/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
#include<stdio.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#ifndef __MINGW32__
#include<sys/wait.h>
#define	SHELL	"/bin/sh"
//打开通道
FILE *PublicPopen(const char *cmdstring, const char *type,pid_t*pidout){
	int		pfd[2];
	pid_t	pid;
	FILE	*fp;
	/* only allow "r" or "w" */
	if ((type[0] != 'r' && type[0] != 'w') || type[1] != 0) {
		errno = EINVAL;		/* required by POSIX.2 */
		return(NULL);
	}

	if (pipe(pfd) < 0)
		return(NULL);	/* errno set by pipe() */

	if ( (pid = fork()) < 0)
		return(NULL);	/* errno set by fork() */
	else if (pid == 0) {							/* child */
		if (*type == 'r') {
			close(pfd[0]);
			if (pfd[1] != STDOUT_FILENO) {
				dup2(pfd[1], STDOUT_FILENO);
				close(pfd[1]);
			}
		} else {
			close(pfd[1]);
			if (pfd[0] != STDIN_FILENO) {
				dup2(pfd[0], STDIN_FILENO);
				close(pfd[0]);
			}
		}
		execl(SHELL, "sh", "-c", cmdstring, (char *) 0);
		_exit(127);
	}
								/* parent */
	if (*type == 'r') {
		close(pfd[1]);
		if ( (fp = fdopen(pfd[0], type)) == NULL)
			return(NULL);
	} else {
		close(pfd[0]);
		if ( (fp = fdopen(pfd[1], type)) == NULL)
			return(NULL);
	}
	*pidout=pid;
	return(fp);
}
//关闭通道
int PublicPclose(FILE *fp,pid_t pid){
	int	 stat;
	/* popen() has never been called */
	//int fd = fileno(fp);
	if ( pid  == 0)
		return(-1);		/* fp wasn't opened by popen() */

	if (fclose(fp) == EOF)
		return(-1);

	while (waitpid(pid, &stat, 0) < 0)
		if (errno != EINTR)
			return(-1);	/* error other than EINTR from waitpid() */

	return(stat);	/* return child's termination status */
}
//离开关闭
int PublicPcloseShutdown(FILE *fp,int pid){
	int		stat;
	/* popen() has never been called */
	//int fd = fileno(fp);
	if ( pid  == 0)
		return(-1);		/* fp wasn't opened by popen() */

	if (fclose(fp) == EOF)
		return(-1);
	kill(pid,SIGKILL);
	while (waitpid(pid, &stat, 0) < 0)
		if (errno != EINTR)
			return(-1);	/* error other than EINTR from waitpid() */

	return(stat);	/* return child's termination status */
	return 0;
}
#endif
